// 它是用来控制API开关用的
// 是后台可控的
// 配置数据在数据库里

use crate::tool_bag::*;
use futures::executor::block_on;
use sea_orm::{ColumnTrait, Condition, EntityTrait, QueryFilter, QuerySelect, QueryTrait, ActiveEnum};
use std::collections::HashMap;
use std::ops::{Deref, DerefMut};
use tokio::sync::RwLock;

lazy_static! {
    /// ! 请不要在 全局中间件 上写锁 ,请使用 读锁
    /// ! 若上写锁,就会把 多线程 变成 单线程,全部请求会在这里堵塞
    pub static ref API_CONTROL: RwLock<ApiControl> = {
        RwLock::new(ApiControl::new())
    };
}


// <(请求方法,api路径),开关>
type ApiSwitchs = HashMap<(String, String), bool>;
/// Api精准控制
#[derive(Debug,Clone)]
pub struct ApiControl(ApiSwitchs);

///: 你可以直接修改内部的hash表,Self继承了它
/// !! 后期在完善,现在也用不到,说不准后期逻辑又又变了~
impl ApiControl {
    fn new() -> Self {
        let mut a = ApiControl(HashMap::new());
        block_on(a.update()); //加载第一次配置信息
        a
    }
    /// 更新自身
    pub async fn update(&mut self) {
        // !!! 存在逻辑问题 , 缘于 表的格式修改, 设计是对的,建表建错了...
        //<< 配置对象,应该加载所有数据
        //<< 配置对象,应该与表数据同步,这意味这修改表需要通过它的数据来修改
        let 已开启功能 = entity_table::功能控制::find()
            .column(table::功_能_控_制::Column::Id)
            .column(table::功_能_控_制::Column::开关)
            .filter(Condition::all().add(table::功_能_控_制::Column::开关.eq(true)))
            .all(*MYSQL_DB)
            .await
            .expect("API精准控制配置更新出现异常!来自:<功能控制>表查询");
        let 已开启功能 = {
            let mut a = HashMap::new();
            for v in 已开启功能 {
                a.insert(v.id, v.开_关); //开关一定是 1
            }
            a
        };

        let mut 已开启的API = entity_table::Api精准控制::find()
            .column(table::api_精_准_控_制::Column::功能控制Id)
            .column(table::api_精_准_控_制::Column::请求方法)
            .column(table::api_精_准_控_制::Column::Api路径)
            .column(table::api_精_准_控_制::Column::开关)
            .column(table::api_精_准_控_制::Column::强制开关)
            .filter(
                Condition::all()//table_enums::Api类型::Rust
					.add(table::api_精_准_控_制::Column::Api类型.eq(table_enums::Api类型::Rust))
					.add(
                    Condition::any()
                        .add(table::api_精_准_控_制::Column::开关.eq(true))
                        .add(table::api_精_准_控_制::Column::强制开关.eq(true)),
                ),
            )
            .all(*MYSQL_DB)
            .await
            .expect("API精准控制配置更新出现异常!来自:<Api精准控制>表查询");

        已开启的API.retain(move |a| {
            a.强_制_开_关.unwrap()
                || (a.开_关
                    && (a.功_能_控_制_id.is_none()
                        || 已开启功能.get(&a.功_能_控_制_id.unwrap()).is_some()))
        });
        for v in 已开启的API {
			self.insert((v.请_求_方_法.to_value().to_string(),v.api_路_径), true);
        }
    }

    /// 更新数据库
    pub async fn update_sql(&self){
        
        todo!()
    }
}

/// ApiControl 继承 ApiSwitchs
impl Deref for ApiControl {
    type Target = ApiSwitchs;
    fn deref(&self) -> &Self::Target {
        &self.0
    }
}
impl DerefMut for ApiControl {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.0
    }
}
